import Testing
import Foundation
@testable import BackDataLibrary

/// BackDataLibrary 测试用例
struct BackDataLibraryTests {
    
    /// 测试iCloud可用性检查
    @Test func testICloudAvailability() async throws {
        let library = BackDataLibrary.shared
        let isAvailable = library.isICloudAvailable()
        
        // 注意：在测试环境中，iCloud可能不可用，这是正常的
        print("iCloud可用性: \(isAvailable)")
    }
    
    /// 测试获取iCloud Documents目录
    @Test func testGetICloudDocumentsDirectory() async throws {
        let library = BackDataLibrary.shared
        let documentsURL = library.getICloudDocumentsDirectory()
        
        if let url = documentsURL {
            print("iCloud Documents目录: \(url.path)")
            #expect(url.path.contains("Documents"))
        } else {
            print("iCloud Documents目录不可用")
        }
    }
    
    /// 测试错误类型的本地化描述
    @Test func testBackupErrorDescriptions() async throws {
        let errors: [BackDataLibrary.BackupError] = [
            .iCloudNotAvailable,
            .fileNotFound,
            .copyFailed,
            .permissionDenied,
            .invalidPath
        ]
        
        for error in errors {
            let description = error.errorDescription
            #expect(description != nil)
            #expect(!description!.isEmpty)
            print("错误类型 \(error): \(description!)")
        }
    }
    
    /// 测试文件备份功能（模拟）
    @Test func testBackupDataFileWithMockFile() async throws {
        let library = BackDataLibrary.shared
        
        // 创建一个临时测试文件
        let tempDir = FileManager.default.temporaryDirectory
        let testFile = tempDir.appendingPathComponent("test_backup.txt")
        let testContent = "这是一个测试备份文件"
        
        try testContent.write(to: testFile, atomically: true, encoding: .utf8)
        
        // 验证文件存在
        #expect(FileManager.default.fileExists(atPath: testFile.path))
        
        // 清理测试文件
        try FileManager.default.removeItem(at: testFile)
        
        print("文件备份测试准备完成")
    }
    
    /// 测试文件列表功能
    @Test func testListBackupFiles() async throws {
        let library = BackDataLibrary.shared
        
        // 使用临时目录进行测试
        let tempDir = FileManager.default.temporaryDirectory
        let testDir = tempDir.appendingPathComponent("test_backup_dir")
        
        // 创建测试目录
        try FileManager.default.createDirectory(at: testDir, withIntermediateDirectories: true)
        
        // 创建一些测试文件
        let testFiles = ["test1.db", "test2.txt", "test3.db"]
        for fileName in testFiles {
            let fileURL = testDir.appendingPathComponent(fileName)
            try "测试内容".write(to: fileURL, atomically: true, encoding: .utf8)
        }
        
        // 测试列出所有文件
        let expectation = expectation(description: "列出所有文件")
        
        library.listBackupFiles(in: testDir) { result in
            switch result {
            case .success(let urls):
                print("找到 \(urls.count) 个文件")
                expectation.fulfill()
            case .failure(let error):
                print("列出文件失败: \(error)")
                expectation.fulfill()
            }
        }
        
        await fulfillment(of: [expectation], timeout: 5.0)
        
        // 测试按扩展名过滤
        let dbExpectation = expectation(description: "列出db文件")
        
        library.listBackupFiles(in: testDir, withExtension: "db") { result in
            switch result {
            case .success(let urls):
                print("找到 \(urls.count) 个.db文件")
                for url in urls {
                    #expect(url.pathExtension == "db")
                }
                dbExpectation.fulfill()
            case .failure(let error):
                print("列出db文件失败: \(error)")
                dbExpectation.fulfill()
            }
        }
        
        await fulfillment(of: [dbExpectation], timeout: 5.0)
        
        // 清理测试目录
        try FileManager.default.removeItem(at: testDir)
    }
}

/// 测试期望辅助函数
private func expectation(description: String) -> TestExpectation {
    return TestExpectation(description: description)
}

/// 等待期望完成的辅助函数
private func fulfillment(of expectations: [TestExpectation], timeout: TimeInterval) async {
    // 简单的等待实现
    for expectation in expectations {
        var fulfilled = false
        let startTime = Date()
        
        while !fulfilled && Date().timeIntervalSince(startTime) < timeout {
            fulfilled = expectation.isFulfilled
            if !fulfilled {
                try? await Task.sleep(nanoseconds: 100_000_000) // 0.1秒
            }
        }
    }
}

/// 简单的测试期望类
private class TestExpectation {
    let description: String
    private(set) var isFulfilled = false
    
    init(description: String) {
        self.description = description
    }
    
    func fulfill() {
        isFulfilled = true
    }
}
